import {
  CommandDialog,
  type CommandDialogPlacement,
  BaseCommand,
  http,
  getQueryParam,
  QueryParamKeys,
} from '@amcax/base';
import { Renderer3D, RendererMgr } from '@amcax/renderer';
import { wsApi } from '../../../../server/wsApi';
import { Box } from '@mui/material';
import i18n from 'i18next';
import { useEffect, useState } from 'react';
import { Vector3 } from 'three';
import { Button, Modal, Spin } from 'antd';
import './modal.scss';
import { clearLocalListDatas } from '../../widgets/RightNavigation/panels/InputPanel';
import { getAirfoilVertexes } from '../cmd-airfoil/cmdAirfoilAPI';
import { initAirfoil } from '../cmd-airfoil-optimize';
import { previewer, userEvents } from '../../../../module';

// 光顺
interface FairingCommandProps {
  title: string;
  onClose: () => void;
  placement: CommandDialogPlacement;
}

const documentId = getQueryParam<string>(QueryParamKeys.DOCUMENT_ID);
function FairingCommand({ title, onClose, placement }: FairingCommandProps) {
  const [optimize, setOptimize] = useState(false);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    initAirfoil();
  }, []);

  const handleExecute = async () => {
    await applyFairing();
    onClose();
  };

  const handlePreview = async () => {
    setLoading(true);
    await previewFairing();
    setLoading(false);
    setOptimize(true);
  };

  const handleClose = () => {
    cancel();
    onClose();
  };

  useEffect(() => {
    // 启动预览接口
    // startAction();
  }, []);

  /**
   * 获取光顺数据
   */
  const getFairingData = async () => {
    const vertexes = await getAirfoilVertexes();
    const originData = {
      data: vertexes,
    };
    const fairingDatas = await new Promise<Array<Vector3>>(async (resolve) => {
      const smoothAddr = `/airfoil/v1/${documentId}/smooth`;
      await http.post(smoothAddr, originData).then((res) => {
        const json = JSON.stringify(res.data.data);
        const pointsPos = JSON.parse(json);
        const points3d = pointsPos.map((item) => {
          return new Vector3(item.x, item.y, 0);
        });
        resolve(points3d);
      });
    });
    return fairingDatas;
  };

  /**
   * 光顺算法预览
   */
  const previewFairing = async () => {
    const data = await getFairingData();
    previewAirfoil(data);
  };

  const updateAirfoil = async () => {
    const dxidJSON = await wsApi.getAppData(documentId + 'dxid');
    const dxid = JSON.parse(dxidJSON);
    const data = await getFairingData();
    const _points = data.map((point: Vector3) => {
      return [point.x, point.y, point.z];
    });
    await wsApi.setParams(dxid, { points: _points });
  };

  /**
   * 应用光顺算法
   */
  const applyFairing = async () => {
    await updateAirfoil();
    previewer.clear();
    clearLocalListDatas();
  };

  /**
   * 取消应用
   */
  const cancel = async () => {
    clearPreview();
  };

  /**
   * 清除预览
   */
  const clearPreview = () => {
    previewer.clear();
  };

  /**
   * 开始预览
   */
  const previewAirfoil = async (data) => {
    const _points = data.map((point: Vector3) => {
      return [point.x, point.y, point.z];
    });
    const res = await execCmd(_points, true);
    const models = getPreviewData(res);
    if (models?.length > 0) {
      previewer.clear();
      previewer.preview(models);
    }
  };

  const execCmd = async (_points, isPreview=false) => {
    const params = {
      c: 'CreateCurve',
      type: 'Bspline',
      a: { mode: 'Approx', points: _points },
      p: isPreview
    }
    return await wsApi.getEngine().execCmd(params);
  };

  const getPreviewData = (data) => {
    return RendererMgr.getRender<Renderer3D>('3d').parsePreviewModels(data);
  };

  return (
    <CommandDialog
      title={title}
      onClose={handleClose}
      placement={placement}>
      <Box
        sx={{
          padding: '0 10px',
        }}>
        <div>通过光顺算法，优化翼型</div>
        <div
          style={{
            display: 'flex',
            paddingTop: '10px',
            paddingBottom: '10px',
            paddingRight: '4px',
            justifyContent: 'right',
          }}>
          <div style={{ paddingLeft: '0px', marginRight: '8px' }}>
            <Button
              style={{ borderRadius: '5px' }}
              onClick={handleClose}>
              {'取消'}
            </Button>
          </div>
          <div style={{ paddingLeft: '0px', marginRight: '8px' }}>
            <Button
              type='primary'
              style={{ borderRadius: '5px' }}
              disabled={optimize}
              onClick={handlePreview}
              // loading={true}
            >
              {'预览'}
            </Button>
          </div>
          <div style={{ paddingRight: '0px' }}>
            <Button
              type='primary'
              style={{ borderRadius: '5px' }}
              disabled={!optimize}
              onClick={handleExecute}>
              {'应用'}
            </Button>
          </div>
        </div>
        <Modal
          open={loading}
          footer={null}
          closable={false}
          centered
          className='transparent-modal'>
          <div style={{ textAlign: 'center', padding: '20px' }}>
            <Spin
              tip='Loading...'
              spinning={loading}
              className='custom-spin'
            />
          </div>
        </Modal>
      </Box>
    </CommandDialog>
  );
}

export const cmdFairing: BaseCommand = {
  id: 'cmdFairing',
  label: '翼型光顺',
  icon: 'commands/airfoil/smooth',
  create: (label: string, onClose: () => void) => (
    <FairingCommand
      title={i18n.t(label)}
      onClose={onClose}
      placement='topLeft'
    />
  ),
  initialDisabled: true,
  subscribeDisabled: (setDisabled: (disabled: boolean) => void) => {
    const listener = (empty: boolean) => {
      setDisabled(empty);
    };
    userEvents.on('sceneEmpty', listener);
    return () => userEvents.off('sceneEmpty', listener);
  },
};
